# 一共有7个代码文件，每个文件对应一个最能体现的原则，请找出每个原则对应的代码文件，然后分析该代码文件是如何体现该原则的。

# 请将文件名修改为相应的原则名称，如：1.单一职责原则.py。并回答以下问题。然后将代码文件上传到之前实验创建的码云仓库中。
# 将码云代码仓库里新建文件夹code_snippets，将代码文件放入该文件夹中。

# 1.运行代码
# 输出如下：
# 普通用户 101 借阅了图书 B1001，最长借阅时间为 14 天。  
# VIP用户 201 借阅了图书 B2002，最长借阅时间为 30 天。

# 2. 指出该代码体现了哪个原则。
# 体现了开闭原则。

# 3. 请说明该代码是如何体现该原则。
# 对扩展开放：
# 在这个例子中，BorrowStrategy是一个抽象基类，定义了一个 borrow 方法作为抽象方法。这个基类为不同的借书策略提供了一个通用的接口。
# 当需要添加新的借书策略时（比如针对会员等级更高的用户），
# 我们只需要创建一个新的类（比如 PlatinumUserBorrowStrategy），继承自 BorrowStrategy 并实现 borrow 方法。这样，新的策略可以很容易地被集成到系统中，而不需要修改现有的代码。

# 对修改关闭：
# LibraryManagementSystem 类依赖于 BorrowStrategy 接口，
# 而不是具体的实现类。这意味着当添加新的借书策略时，LibraryManagementSystem 类的代码不需要被修改。
# 在这个例子中，无论是普通用户还是 VIP 用户借书，LibraryManagementSystem 类的 borrow_book 方法都调用的是 borrow_strategy.borrow(user_id, book_id)。
# 这个调用是面向接口的，因此它不受具体策略实现变化的影响。

from abc import ABC, abstractmethod

# 抽象的借书策略类
class BorrowStrategy(ABC):
    @abstractmethod
    def borrow(self, user_id, book_id):
        pass

# 普通用户的借书策略
class RegularUserBorrowStrategy(BorrowStrategy):
    def borrow(self, user_id, book_id):
        print(f"普通用户 {user_id} 借阅了图书 {book_id}，最长借阅时间为 14 天。")

# VIP用户的借书策略
class VIPUserBorrowStrategy(BorrowStrategy):
    def borrow(self, user_id, book_id):
        print(f"VIP用户 {user_id} 借阅了图书 {book_id}，最长借阅时间为 30 天。")

# 借书功能类，它依赖于抽象的策略类
class LibraryManagementSystem:
    def __init__(self, borrow_strategy: BorrowStrategy):
        self.borrow_strategy = borrow_strategy

    def borrow_book(self, user_id, book_id):
        self.borrow_strategy.borrow(user_id, book_id)

# 测试示例
if __name__ == "__main__":
    # 普通用户借书
    regular_borrow_strategy = RegularUserBorrowStrategy()
    library_system = LibraryManagementSystem(regular_borrow_strategy)
    library_system.borrow_book(user_id=101, book_id="B1001")

    # VIP用户借书
    vip_borrow_strategy = VIPUserBorrowStrategy()
    library_system = LibraryManagementSystem(vip_borrow_strategy)
    library_system.borrow_book(user_id=201, book_id="B2002")
